/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "iot_nfc.h"
#include "iot_wifi.h"
#include "iot_sntp.h"
#include "hi_adc.h"
#include "hi_gpio.h"
#include "ohos_init.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <cmsis_os2.h>
#include <stdbool.h>
#include "network_config_service.h"
#include "iot_netcfg_nan.h"
#include "lwip/sockets.h"
#include "reset.h"
     
#define AFTER_NETCFG_ACTION 2
#define CONFIG_TCP_PORT 8888      // TCP要连接的服务器端口
#define CONFIG_UDP_PORT 9090      // UDP要连接的服务器端口
#define BUFF_SHORT_SIZE 128
#define TCP_BACKLOG 10
#define BUFF_SIZE 512
#define ADC5_CHANNEL 5
#define ADC2_CHANNEL 2
#define ADC_VREF_VOL 1.8
#define ADC_COEFFICIENT 4
#define ADC_RATIO 4096
#define ADC_GPIO05 5
#include "hi_reset.h"
#include "kv_store.h"
#define    SID_KEY        "ssid"
#define    PWD_KEY        "password"
#define    SOFTAP_NAME    "HCIA-DeviceDevelop"
#define    SERVICE_ID     "SmartEnv#"

extern osMutexId_t g_mutexId;

// 在sock_fd 进行监听，在 new_fd 接收新的链接
    int sock_fd, new_fd;

/**************************************************
 * 函数：Creat_UDP_server
 * 功能：创建UDP服务器
 * ***********************************************/
static int Creat_udp_server(){
    int set = 1;
    printf("Socket Udp Start! \n"); 
    struct sockaddr_in sendAddr;

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        printf("socket failed! \n"); 
        return NULL;
    }
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *) &set, sizeof(set)) < 0) {
        printf("open setsockopt failed! errno sockfd = %d\n", sockfd);
        return NULL;
    }
    memset_s(&sendAddr, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in));
    sendAddr.sin_family = AF_INET;
    sendAddr.sin_port = htons(CONFIG_UDP_PORT);
    sendAddr.sin_addr.s_addr = INADDR_BROADCAST;
    printf("Already started!");
    char sendbuf[BUFF_SHORT_SIZE] = SERVICE_ID;
    socklen_t slen = sizeof(sendAddr);
    printf("Send ServiceID %s!\r\n",SERVICE_ID);
    while(1){        
        sendto(sockfd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&sendAddr, slen);
        osDelay(100);
    }
    close(sockfd);
    return 1;
}

/**************************************************
 * 函数：Creat_tcp_server
 * 功能：创建TCP服务器
 * ***********************************************/
static void Creat_tcp_server(){
    osThreadAttr_t attr;

    // 服务端地址信息
    struct sockaddr_in server_sock;
    printf("start TCP Servser! \n");
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket is error\r\n");
        exit(1);
    }
    bzero(&server_sock, sizeof(server_sock));
    server_sock.sin_family = AF_INET;
    server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sock.sin_port = htons(CONFIG_TCP_PORT);

    // 调用bind函数绑定socket和地址
    if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1) {
        exit(1);
    }
    // 调用listen函数监听(指定port监听)
    if (listen(sock_fd, TCP_BACKLOG) == -1) {
        exit(1);
    }
}

/**************************************************
 * 函数：IotWifiInfo_get
 * 功能：获取KV存储
 * ***********************************************/
static int IotWifiInfo_get(char *ssid, int id_size, char *pwd, int pd_size)
{
    int retval = UtilsGetValue(SID_KEY, ssid, id_size);
    if (retval <= 0) {
        printf("no such ssid stored! \n");
        return 0;
    }

    if ( UtilsGetValue(PWD_KEY, pwd, pd_size) < 0 ) {
        printf("ssid(%s) no password stored! \n", ssid);
    } else {
        printf("ssid : %s, pwd : %s! \n", ssid, pwd);
    }

    return 1;
}

/**************************************************
 * 函数：IotWifiInfo_set
 * 功能：设置KV存储
 * ***********************************************/
static void IotWifiInfo_set(char *ssid, char *pwd)
{
    if (UtilsSetValue(SID_KEY, ssid) != 0) {
        printf("store ssid failed! \n");
        return;
    }
    if (UtilsSetValue(PWD_KEY, pwd) != 0) {
        printf("store password failed! \n");
        UtilsDeleteValue(SID_KEY);
        return;
    }
    printf("store password success! \n");
}

/**************************************************
 * 函数：KV_reset_button_GPIO05
 * 功能：复位KV存储（HiSpark UAER按键）
 * ***********************************************/
static int KV_reset_button_GPIO05(void){

    hi_gpio_set_ouput_val(HI_GPIO_IDX_5, HI_GPIO_VALUE1);
    unsigned int ret;
    unsigned short data;
    hi_adc_read(HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_8, HI_ADC_CUR_BAIS_DEFAULT, 0xff);
    ret = (float)data * ADC_VREF_VOL * ADC_COEFFICIENT / ADC_RATIO;
    printf("ret...........%d\r\n",ret);
    if(ret > 1.5){
        return 0;
    } else {
        return 1;
    }

}

void nfc_network_task(const void *arg)
{
    osMutexAcquire(g_mutexId, osWaitForever);
    (void)arg;
    char ssid[BUFF_SIZE] = {0};
    char pwd[BUFF_SIZE] = {0};
    int ret = 0;
    osDelay(100);
    ret = KV_reset_button_GPIO05();
    if (ret) {
        printf("Netconfig Button has pressed! \n");
        if (BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0) {
            printf("BOARD_NetCfgStartConfig failed! \n");
            return;
        } else {
            ret = AFTER_NETCFG_ACTION;
        }
    } else {
        ret = IotWifiInfo_get(ssid, sizeof(ssid), pwd, sizeof(pwd));
        if (ret == 0) {
            if (BOARD_NAN_NetCfgStartConfig(SOFTAP_NAME, ssid, sizeof(ssid), pwd, sizeof(pwd)) < 0) {
                printf("BOARD_NetCfgStartConfig failed! \n");
                return;
            } else {
                ret = AFTER_NETCFG_ACTION;
            }
        }
    }
    if (WifiConnect(ssid, pwd) == 0) {
        osThreadAttr_t attr;
        attr.attr_bits = 0U;
        attr.stack_size = 1024*5;

        attr.name = "Creat_udp_server";
        attr.priority = osPriorityNormal;
        osThreadNew((osThreadFunc_t)Creat_udp_server, NULL, &attr);

        attr.name = "Creat_tcp_server";
        attr.priority = osPriorityNormal;
        osThreadNew((osThreadFunc_t)Creat_tcp_server, NULL, &attr);
    }else{
        printf("ConnectWifi failed! \n");
        if (ret == AFTER_NETCFG_ACTION) {
            NotifyNetCfgResult(NETCFG_DEV_INFO_INVALID);
        }
        RebootDevice(HI_SYS_REBOOT_CAUSE_CMD);
        return;
    }

    if (ret == AFTER_NETCFG_ACTION) {
        printf("Connect wifi success ! \n");
        NotifyNetCfgResult(NETCFG_OK);
        osDelay(100);
        printf("StopNetCfg wifi success ! \n");
        StopNetCfg();
        IotWifiInfo_set(ssid, pwd);
    }
    osMutexRelease(g_mutexId);
    return;
}